﻿// <copyright file="Pair.cs" company="Joe Chung">
// Copyright © 2008 by Joe Chung.
// </copyright>
namespace NScheme
{
    using System;
    using System.Text;

    public sealed class Pair : NScheme.SchemeUtils
    {
        public Pair(object first, object rest)
        {
            this.first = first;
            this.rest = rest;
        }

        public new object first
        {
            get;
            set;
        }

        public new object rest
        {
            get;
            set;
        }

        public override bool Equals(object x)
        {
            if (x == this)
            {
                return true;
            }
            else if (!(x is Pair))
            {
                return false;
            }
            else
            {
                Pair that = (Pair)x;
                return equal(this.first, that.first) && equal(this.rest, that.rest);
            }
        }

        /// <summary>
        /// TODO
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return stringify(this, true);
        }

        public void stringifyPair(bool quoted, StringBuilder buf)
        {
            string special = null;

            if (this.rest is Pair && rest(this.rest) == null)
            {
                if (this.first as string == "quote")
                {
                    special = "'";
                }
                else if (this.first as string == "quasiquote")
                {
                    special = "`";
                }
                else if (this.first as string == "unquote")
                {
                    special = ",";
                }
                else if (this.first as string == "unquote-splicing")
                {
                    special = ",@";
                }
                else
                {
                    special = null;
                }
            }

            if (special != null)
            {
                buf.Append(special);
                stringify(second(this), quoted, buf);
            }
            else
            {
                buf.Append('(');
                stringify(this.first, quoted, buf);

                object tail = this.rest;
                while (tail is Pair)
                {
                    buf.Append(' ');
                    stringify(((Pair)tail).first, quoted, buf);
                    tail = ((Pair)tail).rest;
                }

                if (tail != null)
                {
                    buf.Append(" . ");
                    stringify(tail, quoted, buf);
                }

                buf.Append(')');
            }
        }
    }
}